﻿using JX.Enrollment.Entity;
using JX.Enrollment.Web.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace JX.Enrollment.Web
{
    public partial class Application : System.Web.UI.Page
    {
        # region Declaration
        internal enum Sesyon
        {
            //Enumeration of Page Session.
            Notification, ApplicationForm, ApplicationFormList, SortExpression, RowForDeletion, IsEdit
        }
        internal const string uri = "/Application";
        /// <summary>
        /// Dictionary to sort column from the grid
        /// </summary>
        private Dictionary<string, Func<IEnumerable<ApplicationForm>, IEnumerable<ApplicationForm>>> sortFilters = new Dictionary<string, Func<IEnumerable<ApplicationForm>, IEnumerable<ApplicationForm>>>(StringComparer.OrdinalIgnoreCase)
    {
        { "LastName-Ascending",      list => list.OrderBy(t => t.LastName).ToList()},
        { "LastName-Descending",           list => list.OrderByDescending(t=> t.LastName).ToList()} ,
        { "FirstName-Ascending",           list => list.OrderBy(t => t.FirstName).ToList() },
        { "FirstName-Descending",          list => list.OrderByDescending(t => t.FirstName).ToList() },
        { "MiddleName-Ascending",          list => list.OrderBy(t => t.MiddleName).ToList() },
        { "MiddleName-Descending",          list => list.OrderByDescending(t => t.MiddleName).ToList() },
        { "Type-Ascending",          list => list.OrderBy(t => t.Type).ToList() },
        { "Type-Descending",          list => list.OrderByDescending(t => t.Type).ToList() },
        { "TempNo-Ascending",          list => list.OrderBy(t => t.RefNumber).ToList() },
        { "TempNo-Descending",          list => list.OrderByDescending(t => t.RefNumber).ToList() },
        { "PreviousSchool-Ascending",          list => list.OrderBy(t => t.PreviousSchool).ToList() },
        { "PreviousSchool-Descending",          list => list.OrderByDescending(t => t.PreviousSchool).ToList() },
        { "CreatedDate-Ascending",          list => list.OrderBy(t => t.CreatedDate).ToList() },
        { "CreatedDate-Descending",          list => list.OrderByDescending(t => t.CreatedDate).ToList() },
    };
        #endregion

        #region Events

        protected void Page_Init(object sender, EventArgs e)
        {
            Session[Sesyon.Notification.ToString()] = (Session[Sesyon.Notification.ToString()] == null
                ? false : (bool)Session[Sesyon.Notification.ToString()]);
            Session[Sesyon.ApplicationForm.ToString()] = (Session[Sesyon.ApplicationForm.ToString()] == null
                ? new ApplicationForm() : (ApplicationForm)Session[Sesyon.ApplicationForm.ToString()]);
            ViewState[Sesyon.ApplicationFormList.ToString()] = (ViewState[Sesyon.ApplicationFormList.ToString()] == null
                ? new ApplicationForm[] { } : (IEnumerable<ApplicationForm>)ViewState[Sesyon.ApplicationFormList.ToString()]);
            ViewState[Sesyon.RowForDeletion.ToString()] = (ViewState[Sesyon.RowForDeletion.ToString()] == null
                ? 0 : (Int32)ViewState[Sesyon.RowForDeletion.ToString()]);
            ViewState[Sesyon.IsEdit.ToString()] = (ViewState[Sesyon.IsEdit.ToString()] == null
                ? false : (bool)ViewState[Sesyon.IsEdit.ToString()]);

            lnkAdd.Text = Messages.Student.Add;
            lnkAddNew.Text = Messages.Student.Add;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                IEnumerable<ApplicationForm> studInfo = GetApplicationFormList(true);
                lblNoFound.Visible = ApplicationFormVM.DisplayNotFound(studInfo);
                lnkAddNew.Visible = ApplicationFormVM.DisplayAddNewDeleteButton(studInfo);
                lblNotification.Text = ApplicationFormVM.NotificationMessage;
                lblNotification.Visible = (bool)Session[Sesyon.Notification.ToString()];
                Pnldisplay.Visible = true;
                txtSearch.Attributes.Add("onmouseup", String.Format("onMouseUp({0}{1})", "MainContent_", txtSearch.ID));
                grid.DataSource = studInfo;
                grid.DataBind();
            }
        }

        protected void grid_Sorting(object sender, GridViewSortEventArgs e)
        {
            ViewState[Sesyon.SortExpression.ToString()] = GetSortKey(e);
            PopulateApplicationFormList(Sesyon.ApplicationFormList.ToString(), GetApplicationFormList(false));
        }

        protected void grid_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            try
            {
                switch (e.CommandName)
                {
                    case "EditRec":
                        Edit((Int32)grid.DataKeys[int.Parse(e.CommandArgument.ToString())].Value);
                        DialogBox.Open(myModal);

                        break;
                    case "DeleteRec":
                        Delete((Int32)grid.DataKeys[int.Parse(e.CommandArgument.ToString())].Value);
                        Response.Redirect(uri);

                        break;
                    default:
                        grid.SelectedIndex = -1;
                        if (lblNotification.Visible == true) lblNotification.Visible = false;
                        lnkBacktotop.Visible = (grid.Rows.Count > 12) ? true : false;

                        break;
                }
            }
            catch (Exception ex)
            {
                SetErrorMessage(ex.Message);
            }
        }

        protected void grid_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if ((e.Row.RowType == DataControlRowType.DataRow))
            {
                string NavigateURL = ResolveUrl(("javascript:__doPostBack('ctl00$MainContent$grid','Select$" + e.Row.RowIndex + "')"));

                try {
                    ApplicationForm item = e.Row.DataItem as ApplicationForm;

                    e.Row.Attributes.Add("onClick", NavigateURL);
                    e.Row.Style.Add("cursor", "pointer");
                    e.Row.ToolTip = string.Format("{0} {1}, {2} from {3} as {4}",
                        item.RefNumber.ToString(),
                        item.LastName,
                        item.FirstName,
                        item.PreviousSchool,
                        item.Type);

                    CheckBox chkSelect = (CheckBox)e.Row.FindControl("chkSelect");
                    chkSelect.ID = item.ID.ToString();
                    chkSelect.AutoPostBack = true;
                    chkSelect.CheckedChanged += new EventHandler(this.chkSelect_CheckedChanged);
                }
                catch (Exception ex)
                {
                    ex.Message.ToString();
                }
            }
        }

        protected void lnkSearch_Click(object sender, EventArgs e)
        {
            string search = txtSearch.Text;
            IEnumerable<ApplicationForm> result;
            IEnumerable<ApplicationForm> ApplicationFormList = (IEnumerable<ApplicationForm>)
                ViewState[Sesyon.ApplicationFormList.ToString()];

            result = ApplicationFormList.Where(q => (q.MiddleName + " " + q.FirstName + " " + q.LastName)
                    .ToLower()
                    .Contains(search.ToLower()))
                    .ToList();

            lnkReset.Visible = true;
            if (result.Count() == 0)
            {
                lblNoFound.Visible = true;
                lblNotification.Visible = false;
                lnkReset.Text = "Reset List";
                lnkBacktotop.Visible = false;
            }
            else
            {
                lblNoFound.Visible = false;
                lnkReset.Text = "Link";
                lnkBacktotop.Visible = result.Count() > 12 ? true : false;

                SetErrorMessage(string.Format("There {0} {1} {2}. {3}",
                    result.Count() > 1 ? "are" : "is",
                    result.Count().ToString(),
                    result.Count() > 1 ? "items" : "item",
                    "You may reset the list by clicking this "));
                lnkReset.Visible = true;
            }
            grid.DataSource = result;
            grid.DataBind();

        }

        protected void lnkReset_Click(object sender, EventArgs e)
        {
            this.Visible = false;
            Response.Redirect(uri);
        }

        protected void lnkDeleteSelect_Click(object sender, EventArgs e)
        {
            //get all checked items
            foreach (GridViewRow item in grid.Rows)
            {
                CheckBox chkSelect = (CheckBox)item.FindControl("chkSelect");
                if (chkSelect.Checked)
                {
                    Int32 id = (Int32)grid.DataKeys[item.RowIndex].Value;
                    Delete(id);
                }
            }
            Response.Redirect(uri);
        }

        protected void chkSelect_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox chk = (CheckBox)sender;
            lblNotification.Visible = false;

            if (chk.Checked)
            {
                ViewState[Sesyon.RowForDeletion.ToString()] = (Int32)ViewState[Sesyon.RowForDeletion.ToString()] + 1;
            }
            else
            {
                ViewState[Sesyon.RowForDeletion.ToString()] = (Int32)ViewState[Sesyon.RowForDeletion.ToString()] - 1;
            }
            lnkDeleteSelect.Visible = CountSelected();
            lnkDeleteSelected.Visible = CountSelected();

        }

        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            ApplicationForm ApplicationForm = GetApplicationForm();
            ApplicationForm.LastName = txtLastName.Text;
            ApplicationForm.FirstName = txtFirstName.Text;
            ApplicationForm.MiddleName = txtMiddleName.Text;
            ApplicationForm.PreviousSchool = txtPreviousSchool.Text;
            ApplicationForm.Type = ddlType.Text;
            ApplicationForm.GuardianStudentRelationship = txtRelationship.Text;
           // ApplicationForm.TempNo = txtTempNo.Text;
            ApplicationForm.BirthDate = DateTime.Parse(txtBdate.Text);
            ApplicationForm.SchoolYear = ddlSY.SelectedValue;
            ApplicationForm.Type = ddlType.SelectedValue;
            ApplicationForm.CreatedBy = "espirituj";
            ApplicationForm.CreatedDate = DateTime.Now;

            if (ApplicationFormVM.Update(ApplicationForm) && (ApplicationForm.ID != 0))//update
            {
                Session[Sesyon.Notification.ToString()] = true;
            }
            else if (ApplicationFormVM.Insert(ApplicationForm))//insert
            {
                Session[Sesyon.Notification.ToString()] = true;
            }
            else
            {
                Session[Sesyon.Notification.ToString()] = false;
            }
            RemoveSession();
            Response.Redirect(uri);
        }

        protected void lnkAddNew_Click(object sender, EventArgs e)
        {
            Add();
            DialogBox.Open(myModal);
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            DialogBox.Close(myModal);
        }
        #endregion

        #region Methods
        public void SetErrorMessage(string message)
        {
            Session[Sesyon.Notification.ToString()] = true;
            lblNotification.Text = message;
            lblNotification.Visible = true;
        }

        private void ClearGridviewList()
        {
            //No need to dispose as list is not IDisposable
            var cleareApplicationFormList = new List<ApplicationForm>();
            grid.DataSource = cleareApplicationFormList;
            grid.DataBind();
        }

        private string GetSortKey(GridViewSortEventArgs e)
        {
            //viewstate for sorting
            string sortKey = string.Empty;
            string currentKey = string.Empty;
            string asc = string.Format("{0}-{1}", e.SortExpression, SortDirection.Ascending.ToString());
            string desc = string.Format("{0}-{1}", e.SortExpression, SortDirection.Descending.ToString());

            if (ViewState[Sesyon.SortExpression.ToString()] == null)
            {
                sortKey = asc;
            }
            else
            {
                currentKey = ViewState[Sesyon.SortExpression.ToString()].ToString();
                sortKey = (currentKey == asc)
                    ? sortKey = desc
                    : sortKey = asc;
            }

            return sortKey;
        }

        private IEnumerable<ApplicationForm> GetApplicationFormList(bool forceUpdate)
        {
            IEnumerable<ApplicationForm> ApplicationFormList = new ApplicationForm[] { };

            if (forceUpdate) //Use force Update if you need to refresh the viewstate
                ViewState[Sesyon.ApplicationFormList.ToString()] = null;

            if (ViewState[Sesyon.ApplicationFormList.ToString()] == null)
            {
                ApplicationForm ApplicationForm = new ApplicationForm();
                ApplicationFormList = ApplicationFormVM.GetApplicationFormInfo();
            }
            else
            {
                ApplicationFormList = (IEnumerable<ApplicationForm>)ViewState[Sesyon.ApplicationFormList.ToString()];
            }
            if (ApplicationFormList != null)
            {
                ViewState[Sesyon.ApplicationFormList.ToString()] = ApplicationFormList;
            }
            return ApplicationFormList;
        }

        private void PopulateApplicationFormList(string ListToDisplay, IEnumerable<ApplicationForm> ApplicationForms)
        {
            ClearGridviewList();

            if (ViewState[ListToDisplay] != null)
            {
                IEnumerable<ApplicationForm> ApplicationFormList = (IEnumerable<ApplicationForm>)ViewState[ListToDisplay];
                try
                {
                    if (ApplicationFormList != null)
                    {
                        if (ViewState[Sesyon.SortExpression.ToString()] != null)
                        {
                            string sort = ViewState[Sesyon.SortExpression.ToString()].ToString();
                            ApplicationFormList = sortFilters[sort](ApplicationFormList);
                        }
                        else
                        {
                            ApplicationFormList = ApplicationFormList.OrderBy(t => t.ID).ToList();//default view
                        }
                        grid.DataSource = ApplicationFormList;
                        grid.DataBind();
                    }
                }
                catch (Exception ex)
                {
                    SetErrorMessage(ex.Message);
                }
            }
        }

        void Add()
        {
            Session[Sesyon.Notification.ToString()] = false;
            ApplicationForm ApplicationForm = new ApplicationForm();
            Session[Sesyon.ApplicationForm.ToString()] = ApplicationForm;
            PopulateFields(ApplicationForm);
            txtBdate.Text = DateTime.Now.ToString("MM/dd/yyyy");
            lblModalheader.Text = DialogBox.Student.Add.ToString();
        }

        void Edit(Int32 ID)
        {
            ApplicationForm ApplicationForm = ApplicationFormVM.Get(ID);
            bool result = (ApplicationForm != null ? true : false);
            Session[Sesyon.ApplicationForm.ToString()] = ApplicationForm;

            if (result)
            {
                PopulateFields(ApplicationForm);
            }
            lblModalheader.Text = DialogBox.Student.Update.ToString();
        }

        void Delete(Int32 ID)
        {
            bool result = false;
            result = ApplicationFormVM.Delete(ID);

            if (result)
            {
                Session[Sesyon.Notification.ToString()] = result;
            }
        }

        private ApplicationForm GetApplicationForm()
        {
            ApplicationForm ApplicationForm = new ApplicationForm();
            var sessionApplicationForm = (ApplicationForm)Session[Sesyon.ApplicationForm.ToString()];

            if (sessionApplicationForm.ID != 0)
            {
                ViewState[Sesyon.IsEdit.ToString()] = true;
                ApplicationForm = sessionApplicationForm; //pass value from the session
            }
            else
            {
                ViewState[Sesyon.IsEdit.ToString()] = false;
            }
            return ApplicationForm;
        }

        private void RemoveSession()
        {
            Session[Sesyon.ApplicationForm.ToString()] = null;
            Session.Remove(Sesyon.ApplicationForm.ToString());
        }

        private bool CountSelected()
        {
            bool selected = false;
            if ((Int32)ViewState[Sesyon.RowForDeletion.ToString()] > 0)
            {
                selected = true;
            }
            return selected;
        }

        private void PopulateFields(ApplicationForm ApplicationForm)
        {
            txtLastName.Text = ApplicationForm.LastName;
            txtFirstName.Text = ApplicationForm.FirstName;
            txtMiddleName.Text = ApplicationForm.MiddleName;
            txtPreviousSchool.Text = ApplicationForm.PreviousSchool;
            txtTempNo.Text = ApplicationForm.RefNumber;
            txtRelationship.Text = ApplicationForm.GuardianStudentRelationship;
            txtBdate.Text = ApplicationForm.BirthDate.ToString("MM/dd/yyyy");
            ddlSY.Text = ApplicationForm.SchoolYear;
            ddlType.Text = ApplicationForm.Type;
        }

        #endregion
    }
}